package main

import (
	"bufio"
	"fmt"
	"io"
	"io/ioutil"
	"os"
)

// 文件操作
func MyOpenFile(filePath string) {
	// 打开文件
	fileObj, err := os.Open(filePath)
	if err != nil {
		fmt.Println("文件打开失败")
		return
	}
	// 读取文件
	var tmp = make([]byte, 1024)
	n, err := fileObj.Read(tmp) // n为文件字节大小
	if err != nil {
		fmt.Println("读取文件异常")
		return
	}
	fmt.Println(string(tmp))
	fmt.Printf("文件字节大小：%d", n)
	// 关闭文件 -- defer避免忘记关闭文件
	defer fileObj.Close()
}

// 1.通过循环读取指定字节的文件
func MyReadAllFile(filePath string) {
	fileObj, err := os.Open(filePath)
	if err != nil {
		fmt.Println("文件打开错误")
		return
	}
	defer fileObj.Close()

	for {
		tmp := make([]byte, 1024)
		n, err := fileObj.Read(tmp)
		if err == io.EOF {
			fmt.Println(string(tmp[:n]))
			return
		}
		if err != nil {
			fmt.Println("文件读取异常")
			return
		}
		fmt.Println(string(tmp[:n]))
	}

}

// 2.bufio读取文件
func bufioReadFile(filePath string) {
	fileObj, err := os.Open(filePath)
	if err != nil {
		fmt.Println("文件打开失败")
		return
	}
	defer fileObj.Close()

	//reader := bufio.NewReader(fileObj)
	// 2.1 一行一行读
	/*line, _, err := reader.ReadLine()
	if err != nil {
		fmt.Println("文件读取失败：", err)
	}
	lineStr := string(line)
	fmt.Println(lineStr)*/

	// 2.2 通过循环实现全读
	/*for {
		lineTow, isPrefix, err := reader.ReadLine()
		if err != nil {
			if err.Error() == "EOF" {
				break
			}
			fmt.Println("文件读取失败")
			return
		}
		// 如果行太长，会被分成多段读取
		if isPrefix {
			// 处理长行的情况，这里简单地将它们连接起来
			fmt.Println(string(lineTow))
			continue
		}
		// 打印完整的一行
		fmt.Println(string(lineTow))
	}*/

	// 2.3 正对非英文的文本读取 reader.ReadRune()
	//for {
	//	r, _, err := reader.ReadRune()
	//	if err != nil {
	//		if err.Error() == "EOF" {
	//			break
	//		}
	//		fmt.Println("读取失败：", err)
	//		return
	//	}
	//	fmt.Print(string(r))
	//}

	// 大文件读写
	scanner := bufio.NewScanner(fileObj)
	for scanner.Scan() {
		line := scanner.Text()
		fmt.Println(line)
	}
	if err := scanner.Err(); err != nil {
		fmt.Println("文件读取错误")
	}
}

// 3.ByIoutil读取文件
func readByIoutilFile(filePath string) {
	context, err := ioutil.ReadFile(filePath)
	if err != nil {
		fmt.Println("文件打开失败", err)
		return
	}
	fmt.Print(string(context))
}

func main() {
	// 相对路径是相对go.mod文件路径
	//MyOpenFile("./basicDemo/data/t1.txt")
	//MyReadAllFile("./basicDemo/data/t1.txt")
	bufioReadFile("./basicDemo/data/t1.txt")
	//readByIoutilFile("./basicDemo/data/t1.txt")
}
